<template>
  <div>
      <!-- 面包屑 -->
      <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>权限管理</el-breadcrumb-item>
        <el-breadcrumb-item>角色列表</el-breadcrumb-item>
      </el-breadcrumb>
      <!-- 卡片视图 -->
      <el-card>
        <!-- 添加按钮 -->
        <el-row :gutter="10">
          <el-col :span="6">
            <el-button type="primary" @click="addDialogVisible = true">添加角色</el-button>
          </el-col>
        </el-row>
        <!-- 角色列表区 -->
        <el-table
          :data="rolesList"
          :border="true"
          stripe
          style="width: 100%">
          <!-- 展开列 -->
          <el-table-column
            type="expand"
           >
            <template slot-scope="scope">
              <el-row :class="['bdbottom',i1===0 ? 'bdtop' :'','vcenter']" v-for="(item1,i1) in scope.row.children" :key="item1.id">
                <!-- 一级权限 -->
                <el-col :span="5">
                  <el-tag 
                  closable
                  @close="removeRightById(scope.row,item1.id)"
                  >{{item1.authName}}</el-tag>
                  <i class="el-icon-caret-right"></i>
                </el-col>
                <!-- 二三级权限 -->
                <el-col :span="19">
                  <el-row :class="[i2===0 ? '' :'bdtop','vcenter']" v-for="(item2,i2) in item1.children" :key="item2.id">
                    <!-- 二级权限 -->
                    <el-col :span="6">
                      <el-tag 
                      closable 
                      @close="removeRightById(scope.row,item2.id)"
                      type="success">{{item2.authName}}</el-tag>
                      <i class="el-icon-caret-right"></i>
                    </el-col>
                    <!-- 三级权限 -->
                    <el-col :span="18">
                        <el-tag 
                        closable 
                        type="warning" 
                        v-for="(item3,i3) in item2.children" 
                        :key="item3.id"
                        @close="removeRightById(scope.row,item3.id)"
                        >{{item3.authName}}</el-tag>
                    </el-col>
                  </el-row>
                </el-col>
              </el-row>
            </template>
          </el-table-column>
          <el-table-column
            type="index"
            label="id"
            width="auto">
          </el-table-column>
          <el-table-column
            prop="roleName"
            label="角色名称"
            width="auto">
          </el-table-column>
          <el-table-column
            prop="roleDesc"
            label="角色描述"
            width="auto">
          </el-table-column>
          <el-table-column
            label="操作"
            width="auto">
             <template slot-scope="scope">     
               <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDIalog(scope.row.id)">编辑</el-button>
               <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeUserById(scope.row.id)">删除</el-button>     
               <el-button type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row)"  size="mini">分配权限</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-card>
      <!-- 分配权限的对话框 -->
      <el-dialog
        @close="setRightDialgoClosed"
        title="分配权限"
        :visible.sync="setRightDialogVisible"
        width="50%">
        <!-- 树形控件 -->
        <el-tree 
        :data="rightsList" 
        :props="treeProps" 
        show-checkbox
        default-expand-all
        ref="treeRef"
        :default-checked-keys="defKeys"
        node-key="id"
        ></el-tree>
        <span slot="footer" class="dialog-footer">
          <el-button @click="setRightDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="allotRights">确 定</el-button>
        </span>
      </el-dialog>
       <!-- 添加用户对话框 -->
      <el-dialog
          title="添加用户"
          :visible.sync="addDialogVisible"
          @close="addDialogClosed"
          width="50%">
          <!-- 内容主体区 -->
          <el-form  :model="addForm" ref="addFromRef" :rules="addFormRules" label-width="100px">
              <el-form-item label="角色名称" prop="roleName">
                  <el-input v-model="addForm.roleName" placeholder=""></el-input>
              </el-form-item>
              <el-form-item label="角色描述" prop="roleDesc">
                  <el-input v-model="addForm.roleDesc" placeholder=""></el-input>
              </el-form-item>
              
          </el-form>
          <!-- 底部区 -->
          <span slot="footer" class="dialog-footer">
            <el-button @click="addDialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="addUser">确 定</el-button>
          </span>
      </el-dialog>
       <!-- 修改用户对话框 -->
      <el-dialog
          title="修改用户"
          :visible.sync="eiditDialogVisible"
          @close="editDialogClosed"
          width="50%">
          <!-- 内容主体区 -->
          <el-form  :model="editForm" ref="editFormRef" :rules="editFormRules" label-width="100px">
              <el-form-item label="角色名称" prop="roleName">
                  <el-input v-model="editForm.roleName" placeholder=""></el-input>
              </el-form-item>
              <el-form-item label="角色描述" prop="roleDesc">
                  <el-input v-model="editForm.roleDesc" placeholder=""></el-input>
              </el-form-item>
              
          </el-form>
          <!-- 底部区 -->
          <span slot="footer" class="dialog-footer">
            <el-button @click="eiditDialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="editUserInfo">确 定</el-button>
          </span>
      </el-dialog>
  </div>
</template>

<script>

export default {
  data() {
    return {
      // 角色数据
      rolesList:[],
      // 权限数据
      rightsList:[],
      // 展示分配权限的对话框
      setRightDialogVisible:false,
      // 树形控件属性绑定对象
      treeProps:{
        label:'authName',
        children:'children'
      },
      // 默认选中ID的数组
      defKeys:[],
      // 当前即将分配权限的角色id
      roleId:[],
      // 控制添加对话框显示与隐藏
      addDialogVisible:false,
      // 添加用户表单
      addForm:{
          roleName:'',
          roleDesc:'',
      },
      // 添加用户表单的校验信息
      addFormRules:{
          roleName:[
              {required:true,message:'请输入角色名',trigger:'blur'},
              {min:3,max:10,message:'用户名在3~10之间',trigger:'blur'}
          ],
          roleDesc:[
              {required:true,message:'请输入角色描述',trigger:'blur'},
              {min:3,max:20,message:'用户名在3~20之间',trigger:'blur'}
          ]
      },
      // 控制编辑对话框显示与隐藏
      eiditDialogVisible:false,
      // 查询到的用户信息
      editForm:{},
      // 添加用户表单的校验信息
      editFormRules:{
          roleName:[
              {required:true,message:'请输入角色名',trigger:'blur'},
              {min:3,max:10,message:'用户名在3~10之间',trigger:'blur'}
          ],
          roleDesc:[
              {required:true,message:'请输入角色描述',trigger:'blur'},
              {min:3,max:20,message:'用户名在3~20之间',trigger:'blur'}
          ]
      },
    }
  },
  created() {
    this.getRolesList();
  },
  methods: {
    // 获取角色列表
    async getRolesList(){
          const {data:res} = await this.$http.get('roles')
          if(res.meta.status !==200) return this.$message.error('获取角色列表失败')
          this.rolesList = res.data
          // console.log(this.rolesList);
    },
    // 更具ID删除对应的的权限
    async removeRightById(role,rightId){
      // 弹框提示用户是否删除
      const confirmResult = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err => err)

        if (confirmResult !=='confirm') {
            return this.$message.info('取消了删除！')
          
        }
        const {data:res}  = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
        if(res.meta.status !==200){
          return this.$message.error('删除权限失败')
        }
        // this.getRolesList();
        role.children = res.data
    },
    // 分配权限
    async showSetRightDialog(role){
      this.roleId = role.id
      // 获取权限的数据
      const {data:res} = await this.$http.get('rights/tree')
      if(res.meta.status !==200) return this.$message.error('获取权限列表失败')
      this.rightsList = res.data
      // console.log(this.rightsList);
      // 获取三级节点
      this.getLeafKeys(role,this.defKeys)
      this.setRightDialogVisible = true
      
    },
    // 通过递归函数获取角色所属三级权限id
    getLeafKeys(node,arr){
      if(!node.children){
        return arr.push(node.id)
      }

      node.children.forEach((item)=>{
        this.getLeafKeys(item,arr)
      })
    },
    // 监听分配权限对话框的关闭事件
    setRightDialgoClosed(){
      this.defKeys = []
    },
    // 点击为角色分配角色
    async allotRights(){
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]
      const idStr = keys.join(',')
      const{data:res} = await this.$http.post(`roles/${this.roleId}/rights`,{rids:idStr})
      if(res.meta.status !==200){
        return this.$message.error("分配权限失败")
      }
      this.$message.success('分配权限成功')
      this.getRolesList()
      this.setRightDialogVisible = false
    },
    // 退出dialog框清空数据
    addDialogClosed(){
        this.$refs.addFromRef.resetFields()
    },
    addUser(){
       this.$refs.addFromRef.validate(async valid =>{
           if(!valid) return
           // 发起用户网络请求
          const {data:res} = await this.$http.post('roles',this.addForm)
          if(res.meta.status !=201){
              this.$message.error('添加用户失败')
          }
          this.$message.success('添加用户成功！')
          this.addDialogVisible = false
       //    更新用户列表数据
         this.getRolesList();
       //    console.log(res);
       })
      },
     // 监听编辑清空事件
    editDialogClosed(){
         this.$refs.editFormRef.resetFields()
    },
      // 修改用户信息提交
     editUserInfo(){
        this.$refs.editFormRef.validate(async valid=>{
            if(!valid) return
            // 发起用户信息的数据请求
             const {data:res} = await this.$http.put('roles/'+ this.editForm.roleId,{
                 roleName:this.editForm.roleName,
                 roleDesc:this.editForm.roleDesc
             })
             if(res.meta.status !=200) {
                  return  this.$message.error('更新用户失败！')
                }
            this.eiditDialogVisible = false
            this.getRolesList();
            this.$message.success('修改成功！')
        })
    },
     // 展示编辑用户对话框
     async showEditDIalog(id){
         const {data:res} = await this.$http.get('roles/'+ id)
         if(res.meta.status !==200) return this.$message.error('查询用户信息失败')
         this.editForm = res.data
         this.eiditDialogVisible = true
        //  console.log(this.editForm);
     },
      // 删除用户信息
       async removeUserById(id){
            // 弹框提示
            const confirmResult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).catch(err =>{return err})
            if(confirmResult !=='confirm'){
                return this.$message.info('以取消删除')
            }
           const {data:res} = await this.$http.delete('roles/' + id)
           if(res.meta.status !== 200){
               return this.$message.error('删除用户失败')
           }
           this.$message.success('删除用户成功')
           this.getRolesList();
        }
  },
}
</script>

<style lang="less" scoped>
.bdtop{
  border-top: 1px solid #eee;
}
.bdbottom{
   border-bottom: 1px solid #eee;
}
.vcenter{
  display: flex;
  align-items: center;
}
.el-tag{
  margin: 7px;
}
</style>